<template>
  <div>
    <z-infinite
      v-model="isLoading"
      :isFinished="isFinished"
      @onLoad="getPexelsData"
    >
      <z-waterfall
        class="w-full px-1"
        :data="pexelsList"
        nodeKey="id"
        :column="isMobileTerminal ? 2 : 5"
        :picturePreReading="false"
      >
        <template v-slot="{ item, width }">
          <ItemVue :data="item" :width="width" @click="onDetails" />
        </template>
      </z-waterfall>
    </z-infinite>
    <!-- 详情内容展示 -->
    <transition
      :css="false"
      @before-enter="beforeEnter"
      @enter="enter"
      @leave="leave"
    >
      <pinsVue v-if="isVisiblePins" :id="currentPins.id" />
    </transition>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { getPexelsList } from '@/api/pexels'
import { isMobileTerminal } from '@/utils/flexible'
import { useAppStore } from '@/store/modules/app'
import { storeToRefs } from 'pinia'
import gsap from 'gsap'
import { useEventListener } from '@vueuse/core'
import ItemVue from './item.vue'
import pinsVue from '@/views/pins/components/pins.vue'

// 是否加载中
const isLoading = ref(false)
// 是否加载完成
const isFinished = ref(false)
// 数据列表
const pexelsList = ref([])

const useApp = useAppStore()
const { currentCategory, searchText } = storeToRefs(useApp)

/**
 * 获取数据
 */
let query = {
  page: 1,
  size: 20,
  categoryId: '',
  searchText: ''
}
const getPexelsData = async () => {
  if (isFinished.value) return
  // 判断是否加载完成
  if (pexelsList.value.length > 0) {
    query.page++
  }
  const { list, total } = await getPexelsList(query)
  if (query.page === 1) {
    pexelsList.value = list
  } else {
    pexelsList.value = [...pexelsList.value, ...list]
  }
  if (pexelsList.value.length === total) {
    isFinished.value = true
  }
  // 加载完成后，关闭加载状态
  isLoading.value = false
}

/**
 * 修改分类，重置数据
 */
const resetCategory = (newQuery) => {
  query = { ...query, ...newQuery }
  pexelsList.value = []
  isFinished.value = false
}

/**
 * 监听分类的变化
 */
watch(currentCategory, (currentCategory) => {
  resetCategory({
    page: 1,
    categoryId: currentCategory.id
  })
})

/**
 * 监听searchText的变化
 */
watch(
  () => searchText.value,
  (val) => {
    resetCategory({
      page: 1,
      searchText: val
    })
  }
)

// 详情展示
const isVisiblePins = ref(false)
const currentPins = ref({})

/**
 * 详情
 */
const onDetails = (item) => {
  // 修改路由
  history.pushState(null, null, `/pins/${item.id}`)
  // 展示详情
  currentPins.value = item || {}
  isVisiblePins.value = true
}

/**
 * 监听浏览器后退事件
 */
useEventListener(window, 'popstate', () => {
  isVisiblePins.value = false
})

/**
 * 进入动画前
 */
const beforeEnter = (el) => {
  gsap.set(el, {
    scaleX: 0,
    scaleY: 0,
    transformOrigin: '0 0',
    translateX: currentPins.value.location?.translateX,
    translateY: currentPins.value.location?.translateY,
    opacity: 0
  })
}

/**
 * 进入动画
 */
const enter = (el, done) => {
  gsap.to(el, {
    duration: 0.3,
    scaleX: 1,
    scaleY: 1,
    opacity: 1,
    translateX: 0,
    translateY: 0,
    onComplete: done
  })
}

/**
 * 离开动画
 */
const leave = (el, done) => {
  gsap.to(el, {
    duration: 0.3,
    scaleX: 0,
    scaleY: 0,
    x: currentPins.value.location?.translateX,
    y: currentPins.value.location?.translateY,
    opacity: 0,
    onComplete: done
  })
}
</script>

<style lang="scss" scoped></style>
